package org.funtester.performance.books.chapter05.sectioin2;

import com.alibaba.fastjson.JSONObject;
import org.funtester.performance.books.chapter03.common.ThreadTool;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;

import java.net.URI;
import java.util.Map;

public class JavaWebSocketClient extends WebSocketClient {

    /**
     * 构造方法,传入服务端地址
     * @param serverUri
     */
    public JavaWebSocketClient(URI serverUri) {
        super(serverUri);
    }

    /**
     * 构造方法,传入服务端地址和http头信息
     * @param serverUri
     * @param httpHeaders
     */
    public JavaWebSocketClient(URI serverUri, Map<String, String> httpHeaders) {
        super(serverUri, httpHeaders);
    }

    /**
     * 连接打开时候调用的方法
     * @param serverHandshake
     */
    @Override
    public void onOpen(ServerHandshake serverHandshake) {
        System.out.println("连接打开");
        serverHandshake.iterateHttpFields().forEachRemaining(x -> System.out.println("握手信息  key: " + x + " value: " + serverHandshake.getFieldValue(x)));
    }

    /**
     * 收到消息时候调用的方法
     * @param s
     */
    @Override
    public void onMessage(String s) {
        System.out.println("收到消息: " + s);
    }

    /**
     * 连接关闭时候调用
     * @param i
     * @param s
     * @param b
     */
    @Override
    public void onClose(int i, String s, boolean b) {
        System.out.println("连接关闭,code码: " + i + ",原因: " + s + ",是否由远程服务关闭: " + b);
        close();// 关闭连接
    }

    /**
     * 出错时候调用
     * @param e
     */
    @Override
    public void onError(Exception e) {
        System.out.println("连接异常");
        e.printStackTrace();// 打印异常堆栈信息
        close(1, "客户端异常关闭");// 关闭连接
    }

    @Override
    public void connect() {
        System.out.println("连接中...");
        super.connect();// 建立WebSocket连接
        int retryCount = 0;// 重试次数
        while (true) {
            if (retryCount++ > 3) {// 判断重试次数
                System.out.println("连接失败");
                break;
            }
            ThreadTool.sleep(1000);// 等待1秒
            if (this.isOpen()) {// 判断是否连接成功
                System.out.println("WebSocket客户端状态: " + this.getReadyState().name());
                break;
            }
        }
        System.out.println("连接成功");
    }

    /**
     * 发送消息,json格式
     * @param data
     */
    public void send(JSONObject data) {
        this.send(data.toJSONString());
    }

    /**
     * 关闭连接
     */
    @Override
    public void close() {
        super.close();
        System.out.println("连接关闭");
    }

}
